// MainWindow.cpp
//
#include "MainWindow.h"

#include "ViewInterface/ViewGraphic.h"
#include "src/ViewOpenGL.h"

#include "GLFrame.h"
#include "GraphicScene.h"


#include "MemCheck.h"

using namespace IDS::IDEAS;
using namespace IDS::IDEAS::OpenGLView::Fwk;

//----------------------------------------------------------------------------------------------
// Constructor
MainWindow::MainWindow(ViewInterface::ViewGraphic *owner)
{
	view			= owner;
	glArea			= NULL;
	showProgressBar = false;
	windowWidth		= 0;
	windowHeight	= 0;
}

//----------------------------------------------------------------------------------------------
MainWindow::~MainWindow()
{
	if( view )
		((ViewInterface::ViewOpenGLQT*)view)->closed();
}

//-------------------------------------------------------------------------------------------------
bool MainWindow::preInitializations()
{
	assert( glArea );

	glArea->makeCurrent();
	glArea->init();
	
	getScene()->initialize();
	return true;
}

//-------------------------------------------------------------------------------------------------
OpenGLView::GraphicScene *MainWindow::getScene()
{
	return dynamic_cast<OpenGLView::GraphicScene*>( glArea->scene() ) ;
}


//-------------------------------------------------------------------------------------------------
bool MainWindow::postInitializations()
{
	assert( glArea  );
	getScene()->postInitializations();

	return true;
}

//----------------------------------------------------------------------------------------------
void MainWindow::setSceneSettings(ViewInterface::GraphicsViewSettings *settings)
{
	assert( glArea );
	getScene()->setSettings(settings);
}


// ------------------------------------------------------------------------------------------------
//void MainWindow::sendEventToApp(ViewInterface::Event<ViewInterface::ViewEventHandler> *event)
void MainWindow::sendEventToApp(ViewInterface::ViewEventBase *event)
{
	view->sendEvent(event);
}

// ------------------------------------------------------------------------------------------------
void MainWindow::setBackgroundColor( const ViewInterface::Color &bk )
{
	assert( glArea );
	getScene()->setBackgroundColor( bk );
}

// ------------------------------------------------------------------------------------------------
void MainWindow::setBackgroundColor( const ViewInterface::Color &top, const ViewInterface::Color &btm )
{
	assert( glArea );

	getScene()->setBackgroundGradient( top, btm );
}

// ------------------------------------------------------------------------------------------------
std::string MainWindow::getResourceDir()
{
	return ((ViewInterface::ViewOpenGLQT*)view)->getResourceDir();
}

// ------------------------------------------------------------------------------------------------
ViewInterface::ViewGraphic::Status MainWindow::getSceneStatus()
{
	return ((ViewInterface::ViewOpenGLQT*)view)->getStatus();
}

// ------------------------------------------------------------------------------------------------
bool MainWindow::insertObjects(const std::vector<ViewInterface::ViewObject*> &objs)
{
	assert( glArea );

	GraphicScene *gs = getScene();

	gs->resetCurrentAction();
	gs->resetViewStatus(true);

	int rejected = 0;
	const double iSize = 1.0 / objs.size();
	setStatusPercentage(0);
	for(size_t i=0; i<objs.size(); ++i)
	{
		if( !gs->insertObject(objs[i]) )
			rejected++;

		setStatusPercentage( (i+1)*iSize  );
	}
	setStatusPercentage(1.0);

	//printf("\n.:: Total Rejected: %d of %d",rejected,objs.size() );

	gs->updateSceneBoundingBox();
	gs->computeObjectsVisibility();
	gs->updateVisibleObjects();
	gs->invalidate();

	return (rejected == 0);
}

// ------------------------------------------------------------------------------------------------
bool MainWindow::insertObject(const ViewInterface::ViewObject& obj)
{
	assert( glArea );

	GraphicScene *gs = getScene();

	gs->resetCurrentAction();
	gs->resetViewStatus(true);

	bool r = gs->insertObject( (const_cast<ViewInterface::ViewObject*>(&obj)) );

	if( r ) 
	{
		gs->updateSceneBoundingBox();
		gs->computeObjectsVisibility();
		gs->updateVisibleObjects();
		gs->invalidate();
	}

	return r;
}

// ------------------------------------------------------------------------------------------------
bool MainWindow::removeObjects(const std::vector<ViewInterface::Identifier> &objs)
{
	assert( glArea );

	GraphicScene *gs = getScene();

	bool r = true;

	gs->resetCurrentAction();
	gs->resetViewStatus(true);

	const double iSize = 1.0 / objs.size();
	setStatusPercentage(0);
	for(size_t i=0; i<objs.size(); ++i)
	{
		r &= gs->removeObject(objs[i]);
		setStatusPercentage( (i+1)*iSize  );
	}
	setStatusPercentage(1.0);

	gs->updateSceneBoundingBox();
	gs->computeObjectsVisibility();
	gs->updateVisibleObjects();
	gs->invalidate();

	return r;
}

// ------------------------------------------------------------------------------------------------
void MainWindow::startClipMode(ViewInterface::Identifier imgID)
{
	assert(glArea);

	GraphicScene *gs = getScene();

	gs->startClipMode( imgID );
}

// ------------------------------------------------------------------------------------------------
bool MainWindow::removeObject(const ViewInterface::Identifier &obj)
{
	assert( glArea );

	GraphicScene *gs = getScene();

	gs->resetCurrentAction();
	gs->resetViewStatus(true);

	bool r = gs->removeObject( obj );

	if( r ) 
	{
		gs->updateSceneBoundingBox();
		gs->computeObjectsVisibility();
		gs->updateVisibleObjects();
		gs->invalidate();
	}

	return r;
}

// ------------------------------------------------------------------------------------------------
bool MainWindow::removeAllDomainObjects()
{
	assert( glArea );

	GraphicScene *gs = getScene();

	gs->resetCurrentAction();
	gs->resetViewStatus(true);

	return gs->removeAllObjects();
}

// ------------------------------------------------------------------------------------------------
void MainWindow::removeAllLocalObjects()
{
	assert( glArea );

	GraphicScene *gs = getScene();

	gs->resetViewStatus(true);
	gs->resetCurrentAction();

	gs->removeAllLocalObjects();
}


// ------------------------------------------------------------------------------------------------
bool MainWindow::refreshLocalObjects()
{
	assert( glArea );

	return getScene()->refreshLocalObjects();
}

// ------------------------------------------------------------------------------------------------
void MainWindow::setSceneStatus(ViewInterface::ViewOpenGLQT::Status s)
{
	assert( glArea );

	getScene()->setStatus( s );
}

// ------------------------------------------------------------------------------------------------
void MainWindow::redraw()
{
	assert( glArea );

	glArea->invalidateScene();
}

// ------------------------------------------------------------------------------------------------
void MainWindow::fitView()
{
	assert( glArea );

	getScene()->fitView();
}

// ------------------------------------------------------------------------------------------------
void MainWindow::fitView(const IDSBox &ulbr)
{
	assert( glArea );

	getScene()->fitView(ulbr.minCoord,ulbr.maxCoord);
}

// ------------------------------------------------------------------------------------------------
void MainWindow::fitView(const ViewInterface::Identifier &id)
{
	assert( glArea );

	getScene()->fitView( id );
}

// ------------------------------------------------------------------------------------------------
void MainWindow::hilightObjects(const std::vector<ViewInterface::Identifier>& objs)
{
	assert( glArea );

	getScene()->hilightObjects( objs );
}

// ------------------------------------------------------------------------------------------------
void MainWindow::selectObjects(const std::vector<ViewInterface::Identifier>& objs)
{
	assert( glArea );

	getScene()->selectObjects( objs );
}

//// ------------------------------------------------------------------------------------------------
//MainWindow::ClientSize MainWindow::getClientSize()
//{
//	assert( glArea );
//
//	//getScene()->
//}
